import { WorkSheet, Range } from "xlsx";
import { consts } from "./consts";
import { IColumnProps } from "devextreme-react/data-grid";


//样本来源表
export type SampleTable = {
    rn: number,//行号
    guid: string; // 默认值为 newid()
    tableName: string; // 表名，表名可以使用 {data_id} 替代年度
    tableTitle: string; // 表标题
    isVoucher: boolean; // 是否财务凭证表，默认值为 0
    isCustom: boolean; // 是自定义，默认值为 1
    orderIndex: number; // 排序号，默认值为 0
    sampleTextFields: string; // 抽样项目字段,,逗号分隔
    sampleNumFields: string;  // 抽样金额字段,逗号分隔
    sortFields: string;//排序字段,逗号分隔
    enabled: boolean; // 是否启用，默认值为 1
    remarks: string;
    fieldsInfo: string,//表的全部字段信息文本

    sampleTextFieldsArray: string[]; // 抽样项目字段 运行时
    sampleNumFieldsArray: string[]; // 抽样金额字段 运行时
    sortFieldsArray: string[];//排序字段

    sampleAllFieldsArray: SampleField[];//表的全部字段信息
    dataId?: string;//
    typedSampleInfo?: TypedSampleInfo;//样本分类列表 运行时,tableSamplingRecord.tsx 用到
    tableTitleDisplayText?: string;//运行时赋值
};
export type SampleField = {
    guid: string; // guid varchar(50) default newid()
    tableName: string; // tableName varchar(100) --表名
    fieldName: string; // fieldName varchar(50) --字段名称
    fieldTitle: string; // fieldTitle varchar(100) --字段标题
    isKey: boolean; // isKey bit default(0) --是否关键字段
    isNum: number; // isNum bit default(0) --是否数字
    align: string; // align varchar(10) --对齐方式 left/center/right
    displayWidth: number; // displayWidth int --显示宽度
    displayFormat: string; // displayFormat varchar(100) --显示格式
    orderIndex: number; // orderIndex int default(0) --排序号
    visible: boolean; // enabled bit default(1) --是否显示
    enabled: boolean; // enabled bit default(1) --是否启用
    remarks: string; // remarks varchar(200)
}
export type ExcelTable = SampleTable & {
    sheet: WorkSheet;// 工作表
    range: Range;// 表格范围
    totalCount: number;//表页总行数据
    tableRowsData: any[];//表数据的json数组
    excelFields: ExcelField[];//字段信息,
    dataRowCount: number;//数据行数
    titleRowNo: number;//标题行,从1,2,3开始
    endRowNo: number;//结束行,从1,2,3开始
};
//Excel字段
export type ExcelField = SampleField & {
    textMaxLen: number;//文本最大长度
    fieldSql?: string;//字段sql
};
//合并进度信息
export type ProgressInfo = {
    progressValue: number; //进度数据[0..100]
    progressText?: string; //进度说明
};
/**
 * 账套信息
 */
export type AccountInfo = {
    ID: string,
    displayName: string,
    zcbfID: string,
    zcbfName: string,
    Data_ID: string,
    ND: string,
    byMonth: string,
    aDateS: string,
    aDateE: string,
    Data_ID_Pre: string,
    Data_ID_Next: string,
    CWSoftName: string,
    importDate: string,
    importResult: string,
    importRemark: string,
}
//抽样项目
export type SampleItem = {
    itemName: string;//抽样项目名称
    assertion: string[];//认定: 存在发生
}

export enum OverallMode {
    overallAdd = 'overallAdd',
    overallEdit = 'overallEdit',
    view = 'view',
    select = 'select',
    sampledList = 'sampledList',//已抽样本列表
    sampleListManualAdd = 'sampleListManualAdd',//未抽样本列表
}
export type RetDataInfo = {
    rowsData: any[],
    totalCount: number
    whereSqlParams?: WhereSqlParams,//界面查询参数
    fieldsFilterWhereSql?: string,//字段过滤条件
}
/**
 * 抽样项目总休
 */
export type ProjectOverallProps = {
    sampleTableList: SampleTable[],//编辑时,数据库不保存
    setSampleTableList?: (value: SampleTable[]) => void,

    curSampleTable?: SampleTable,
    setCurSampleTable: (value: SampleTable) => void,

    accountInfoList: AccountInfo[],
    curDataId: string,
    setCurDataId: (value: string) => void,

    curWhereSqlParams?: WhereSqlParams,//sql条件参数
    setCurWhereSqlParams: (value: WhereSqlParams) => void,

    curSampleTableTotalCount?: number,//当前表总行数
    curSampleTableAmountSum?: number,//当前表总金额
    // setCurSampleTableTotalCount?: (value: number) => void

    curSampleItem: SampleItem;//抽样项目
    setCurSampleItem: (value: SampleItem) => void,

    overallMode: OverallMode, //总体界面的模式,确定样本总体/浏览/选择

    fixedWhereSql?: string,//固定的where sql: 如 and jfje>1000, 需要有And;  一艉是 /浏览/选择 模式下可以有值

    events?: {//事件
        onLoadData?: (retDataInfo: RetDataInfo) => void;//每次查询完数据后的回调
        onSelectionChanged?: (e: any) => void;//表格选择事件
        onRowDblClick?: (e: any) => void;//表格双击事件
        onManualAddSample?: (e: any) => void;//手动添加样本事件
        onBeforeExportData?: (retDataInfo: RetDataInfo) => void;//输出前数据处理

    }
    exportFileNameOnly?: string,//输出文件名


    isAutoQueryData?: boolean,


}
//凭证查询参数
export type FormQueryParams = {
    dataId: string,
    kmbhOperator: string,
    kmbhStr: string,
    kmmcStr: string,
    dfkmOperator: string,
    dfkmStr: string,
    hsxmStr: string,
    jeFx: string,
    jeOperator: string,
    jeStartValue: number,
    jeEndValue: number,
    pzlxStr: string,
    zyStr: string,
    monthStartStr: string,
    monthEndStr: string,
    includeJzpz: boolean,//包含结转凭证
    // xswzpzCheck: false,
    // checkQueryContent: true
}

export type AdvQueryParam = {
    keyDataString: string,
    conditionsName: string,
    sqlType: string,
    isNum: number
    keyString?: string,
    rowConditionsData?: string,

    fieldInfo?:DbFieldInfo;//运行时
}
//抽样的sql参数
export type WhereSqlParams = {
    dbname: string,
    isAdvQuery: boolean,
    advQueryParams: AdvQueryParam[],
    //  accountInfoList: AccountInfo[],
    yearMonths: string[],//[20170101,20170212]
    formQueryParams: FormQueryParams,

}
//抽样步骤内容
export type SampleStep = {
    step0Content?: any,
    step1Content?: any,
    step2Content?: any,

    step0Display?: string,
    step1Display?: string,
    step2Display?: string,

    //能否 渲染
    step0CanRender?: boolean,
    step1CanRender?: boolean,
    step2CanRender?: boolean
}
/**
 * 抽样参数的属性
 */
export type SampleParmeterProps = {
    sampleStepInfoOfParams?: SampleStepInfo;//传入的

}
/**
 * 抽样步骤信息
 */
export type SampleStepInfo = {
    guid?: string,//抽样记录的guid
    stepCurrent?: number;
    step0CanRender?: boolean;//第1 步是否可以渲染
    step1CanRender?: boolean;//第2 步是否可以渲染
    step2CanRender?: boolean;//第3 步是否可以渲染
    sampleMethodActiveKey?: string,//统计抽样或非统计抽样的名称
    projectOverallProps?: ProjectOverallProps,//抽样项目总休属性 第一步的, 在点击下步才有值
    sampleParameterValues?: SampleParameterValues,//抽样参数 第二步,  在点击下步才有值
}

export enum SampleMethod {
    random = '随机抽样',
    system = '系统抽样',
    layer = '分层抽样',
    manual = '任意抽样',
    pps = 'PPS抽样',//PPS（Probability Proportional to Size）抽样的核心思想是金额越大，被抽中的概率越高
}

/***
 * 样本分类列表
 */
export type TypedSampleInfo = {

    specialSampleList: any[];//特殊样本
    specialSampleTextFieldValues: string[];//特殊样本

    amountMajorSampleList: any[];// 金额重大样本列表
    amountMajorSampleTextFieldValues: string[];// 金额重大样本列表

    manualAddSampleList: any[]// 手动添加样本列表
    manualAddSampleTextFieldValues: string[]// 手动添加样本列表

    // normalSampleList?: any[];//一般样本
    // normalSampleTextFieldValues?: string[];//一般样本

}
/**
 * 分类样本文本值
 */
export type TypedSampleTextFieldValues = {

    specialSampleTextFieldValues: string[];//特殊样本

    amountMajorSampleTextFieldValues: string[];// 金额重大样本列表

    manualAddSampleTextFieldValues: string[]// 手动添加样本列表

    normalSampleTextFieldValues: string[];//一般样本
}
//样抽样样本列表的属性
export type SamplingSampleListProps = {
    // typedSampleInfo: TypedSampleInfo,
    // setTypedSampleInfo: (value: TypedSampleInfo) => void,
    sampleStepInfo: SampleStepInfo
}
/**
 * 样本量计算方式
 */
export enum SampleSizeMethod {
    systemIn = 'systemIn',
    systemOut = 'systemOut',
}
export type SampleSizeMethodList = [
    { id: SampleSizeMethod.systemIn, text: '系统内' },
    { id: SampleSizeMethod.systemOut, text: '系统外' }
]
/**
 * 非统计抽样参数
 */
export type NonStatSampleParameter = {
    tolerableMiss: number //可容忍错报
    amountMajorMin: number//金额重大下限
    majorMisstatementRisk: string//重大错报风险水平 最高/高/中/低
    otherSubstantiveRisk: string//其他实质性风险 最高/高/中/低
    measurementSampleSize: number//	E.样本规模

    sampleMethod: SampleMethod//抽样方法 

    specialAmountSum?: number//特殊样本 金额合计
    specialSampleSize?: number//特殊样本 个数
    specialWhereSql?: string//特殊样本 wheresql
    specialSampledNumFields?: SampledNumFields//特殊样本 已抽样字段统计值

    amountMajorAmountSum?: number//金额重大样本 金额合计
    amountMajorSampleSize?: number//金额重大样本  个数
    amountMajorWhereSql?: string//金额重大样本 wheresql
    amountMajorSampledNumFields?: SampledNumFields//金额重大样本 已抽样字段统计值

    lessThanUnimportantMaxSampleSize?: number//小于等于极不重要上限的个数
    lessThanUnimportantMaxSampleSum?: number//小于等于极不重要上限的金额

    greaterThanAmountMajorMinSampleSize?: number//大于等于金额重大下限的个数    
    greaterThanAmountMajorMinSampleSum?: number//大于等于金额重大下限的金额

    unimportantMax: number//极不重要上限
    unimportantAmountSum?: number//极不重要样本 金额合计 
    unimportantSampleSize?: number//极不重要样本  个数
    unimportantWhereSql?: string//极不重要样本 wheresql


    toBeTestAmountSum?: number//待测试的金额合计
    toBeTestSampleSize?: number//待测试的样本  个数
    toBeTestWhereSql?: string//暂时不用,运行时计算

    majorProjectSize?: number;//F.重大项目数量 
    needTestAllSampleSize?: number//G.需测试的全部数量(G=E+F)  个数  

    guaranteeCoefficient?: number,//GuaranteeCoefficient,//保证系数

    randomSampleParams?: RandomSampleParams,//随机抽样 参数
    systemSampleParams?: SystemSampleParams,//系统抽样 参数
    layerSampleParams?: LayerSampleParams,//分层抽样 参数
    manualSampleParams?: ManualSampleParams,//任意抽样 参数
    ppsSampleParams?: PPSSampleParams,//PPS抽样 参数

    manualAddParams?: ManualSampleParams,//样本列表手工追加的样本 参数

    sampledResult?: SampledResult//使用第2步 抽样方法抽取结果 不包含 重大项目、特殊项目、手工增加的

    sampledAllSampleSize?: number//已抽取的全部样本:抽样方法抽取的、重大项目、特殊项目、手工增加的

    sampleSizeMethod?: SampleSizeMethod  //样本量计算方式

}
//统计抽样参数
export type StatSampleParameter = NonStatSampleParameter & {
    expectedOverallMiss?: number//D.预计总体错报
    sampleInterval?: number;//样本间隔

    riskCoefficient?: number;//风险系数,查表

    acceptableRisk?: string;//可接受风险水平(误受风险) 百分数 
    acceptableDevSize?: number;//可接受的偏差数量(高估错报数量)

    expansionCoefficient?: number; // 扩张系数
}

export type SampleParameterValues = NonStatSampleParameter | StatSampleParameter;

/* export enum RandomSampleMethod  { 

} */
/**
 * 随机抽样 参数
 */
export type RandomSampleParams = {
    extractNumber: number;//抽取数量
    useReproducible: boolean;//是否使用可重复抽取
    seed: number;//种子
}
//pps抽样
export type PPSSampleParams = RandomSampleParams;

export type SampleSortField = {
    fieldName?: string;//字段名
    sortType?: string;//排序类型 asc/desc
    isAbs?: boolean;//绝对值
}
//抽取方式
export enum SystemExtractType {
    asc = consts.asc,
    desc = consts.desc
}
export enum LayerExtractType {

    amountBigToSmall = consts.amountBigToSmall,
    amountSmallToBig = consts.amountSmallToBig,
    amountRandom = consts.amountRandom

}
export type LayerRange = {
    guid?: string;
    orderIndex?: number;//序号
    rangeText?: string;//区间
    rangeValue?: number;//<=金额边界
    unSampleSize?: number;//未抽样数量
    needSampleSize?: number;//抽样数量
    rangeWhereSql?: string;//范围条件

    sampledResult?: SampledResult;
}
/**
 * 系统抽样 参数
 */
export type SystemSampleParams = {
    sampleSortFields?: SampleSortField[];//抽样排序字段,规定3个
    extractType?: SystemExtractType;//抽取方式
    extractNumber?: number;///抽取数量
    interval?: number;//间隔
}
export type LayerSampleParams = {
    //sampleSortFields?: SampleSortField[];//抽样排序字段,规定3个
    extractType?: LayerExtractType;//抽取方式
    layerRanges?: LayerRange[];
    // isManualEdit?: boolean;//是否手手动编辑过
}
/**
 * 任意抽样 参数
 */
export type ManualSampleParams = SampledResult & {
    manualWhereSql?: string;//任意抽样的sql条件参数
};
//抽样方法的参数
export type SampleMethodProps = {
    sampleParameterValues: SampleParameterValues,//NonStatSampleParameter | StatSampleParameter,
    setSampleParameterValues: (value: any) => void,//NonStatSampleParameter | StatSampleParameter
    projectOverallProps?: ProjectOverallProps;
}
//保证系数
/* export type GuaranteeCoefficient = {
    significantMissColName?: string,//重大错报列名 highest/high/middle/low
    significantMissRowName?: string,//重大错报行名 highest/high/middle/low
    significantMissValue?: number,//重大错报值
} */
/**
 * 样本的大小和总金额
 */
export type SampleSizeAndAmount = {
    sampleSize: number,
    amountSum: number,
    sampledNumFields?: SampledNumFields,
}
/**
 * 样本信息 ,textFields的各个值列表
 */
export type SampledInfo = {
    amountFieldValue: number,//总金额
    [key: string]: string | number;//

}
/**
 * 已头样字段
 */
export type SampledNumFields = {
    [fieldName: string]: {
        //sampleSize: number,
        amountSum: number,
    }
}
/**
 * 已抽样结果
 */
export type SampledResult = {
    sampledSize: number;//已抽样数量
    sampledAmountSum: number;//已抽样金额合计
    sampledList: SampledInfo[];//已抽的样本列表 
    sampleTextFieldValues: string[];//已抽样本的文本字段值
    sampledNumFields?: SampledNumFields
}
//样本类型
export enum SampleType {
    special = consts.specialSampleType,
    amountMajor = consts.amountMajorSampleType,
    manualAdd = consts.manualAddSampleType,
    normal = consts.normalSampleType,
}
/**
 * 抽样记录表
 */
export type SampleReord = {
    guid: string,
    samplePeriod: string;// nvarchar(255), -- 抽样期间
    sampleSource: string;// nvarchar(255), -- 样本来源
    itemName: string;// nvarchar(255), -- 抽样项目
    assertion: string;// nvarchar(255), -- 相关认定
    sampleMethod: string;// nvarchar(255), -- 抽样方法
    sampleStepInfo: string | SampleStepInfo;// nvarchar(max), -- 抽样步骤信息
    sampleStepInfoStr: string;// nvarchar(max), -- 抽样步骤信息
    createUser: string;// nvarchar(255), -- 操作人
    createTime?: string;// dateTime default getDate() -- 操作时间

    sampleMethodText?: string;//运行时


}
//抽样记录编辑类型
export enum SampleRecordEditType {
    add = 'add',
    edit = 'edit',
    view = 'view'
}

/**
 * 抽样记录编辑信息
 */
export type SampleRecordEditInfo = {

    sampleRecordEditType: SampleRecordEditType,

    sampleStepInfo?: SampleStepInfo,//edit时有值,add没有值
    //保存
    saveSampleRecord: (sampleStepInfo: SampleStepInfo) => Promise<void>,
    //关闭
    closeSamplingRecordPopup: (isFinished: boolean) => void,
    //保存并刷新
    saveSampleRecordAndRefresh: (sampleStepInfo: SampleStepInfo) => Promise<void>,
}
/**
 * 样本记录参数
 */
export type TableSamplingRecordParams = {
    sampleTableList?: SampleTable[],
    curSampleTable?: SampleTable,
    accountInfoList?: AccountInfo[],
    curDataId?: string,
    columns?: IColumnProps[],
}
export type SampleListTimes = {
    textFieldValues: string,
    times: number,
    sampleType: string,
}


/**
 * 数据库字段信息
 */
export type DbFieldInfo = {
    tableName: string,
    fieldName: string,
    dataType: string,
    maxLen: number,
    nullable: string,
    orderIndex: number,
    precision: number,
    scale: number,
    isComputed: number,//是否计算字段 计算字段不导入

    fileFieldName: string,//文件中的字段名,可能大小定不一样
    fileFieldMaxLen: number,//文件中数据的最大长度
}